import {
  Body,
  Controller,
  Get,
  HttpException,
  HttpStatus,
  Logger,
  Param,
  Post,
  Render,
  Req,
  Res,
} from '@nestjs/common';
import { AppService } from './app.service';
import { Request, Response } from 'express';
import { DbService } from './db/db.service';
import { HashService } from './hash/hash.service';

@Controller()
export class AppController {
  private logger = new Logger(AppController.name);

  constructor(
    private readonly appService: AppService,
    private readonly dbService: DbService,
    private readonly hashService: HashService,
  ) {
    // this.logger.debug(JSON.stringify(process.env));
  }

  private hashToUrl(req: Request, route: string, hash: string) {
    const ref = `${req.protocol}://${process.env.HOST}/`;
    this.logger.debug(`Get Referer${ref}`);

    const url = new URL(ref);
    url.pathname = `${route}/${hash}`;

    return url.toString();
  }

  private async addText(text: string) {
    this.logger.debug(`Add Text ${text}`);

    const hash = this.hashService.hash(text);
    const rst = await this.dbService.setText(hash, text);
    if (rst) {
      return hash;
    } else {
      throw new HttpException('存储失败', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  @Get('/')
  @Render('shorter')
  root() {
    return {
      AUTH_TOKEN: process.env.AUTH_TOKEN,
    };
  }

  // 创建短链
  @Post('/s/')
  async genShorter(@Body('link') link: string, @Req() req: Request) {
    if (link == null || link.length < 7 || link.length > 1024 * 10) {
      throw new HttpException('文本长度不合法', HttpStatus.BAD_REQUEST);
    }

    this.logger.debug(`Add ShortLink ${JSON.stringify(link)}`);

    const hash = await this.addText(link);
    return {
      link: this.hashToUrl(req, 'r', hash),
    };
  }

  // 存储文本
  @Post('/p/')
  async paste(@Body('text') text: string, @Req() req: Request) {
    if (text == null || text.length === 0 || text.length > 1024 * 10) {
      throw new HttpException('文本长度不合法', HttpStatus.BAD_REQUEST);
    }

    this.logger.debug(`Add ShortLink ${JSON.stringify(text)}`);

    const hash = await this.addText(text);
    const url = this.hashToUrl(req, 't', hash);

    return {
      url,
    };
  }

  // 跳转短链
  @Get('/r/:hash')
  async redirect(@Param('hash') hash: string, @Res() res: Response) {
    const rst = await this.dbService.getText(hash);

    if (rst !== null) {
      res.status(HttpStatus.FOUND).redirect(rst);
    } else {
      res.status(HttpStatus.NOT_FOUND);
    }
  }

  // 获取文本
  @Get('/t/:hash')
  async text(@Param('hash') hash: string) {
    this.logger.debug(`Get Text ${hash}`);

    const rst = await this.dbService.getText(hash);

    this.logger.debug(`Get Result ${rst}`);

    if (rst !== null) {
      return {
        text: rst,
      };
      // res.send(rst);
    } else {
      throw new HttpException('找不到', HttpStatus.NOT_FOUND);
      // res.status(HttpStatus.NOT_FOUND);
    }
  }

  @Get('/list')
  async list() {
    const list = await this.dbService.keys();
    return list;
  }
}
